/* 
 * File:   EditarCampania.cpp
 * Author: agu
 * 
 * Created on 22 de junio de 2014, 2:43
 */

#include "editor_EditarCampania.h"
#include <iostream>
#include <sstream>
#include <dirent.h>
#include <fstream>
#include <iostream>
#include <fstream>  

using std::stringstream;

EditarCampania::EditarCampania() {
    this->builder = Gtk::Builder::create();
    try {
        this->builder->add_from_file("gladeInterfaces/nuevaCampania.glade");
    } catch (const Glib::FileError& ex) {
        std::cout << "FileError: " << ex.what() << std::endl;

    } catch (const Glib::MarkupError& ex) {
        std::cout << "MarkupError: " << ex.what() << std::endl;

    } catch (const Gtk::BuilderError& ex) {
        std::cout << "BuilderError: " << ex.what() << std::endl;

    }
    this->loadWidgets();
    this->createModel();
    this->connectWidgets();
}

void EditarCampania::loadWidgets() {
    this->builder->get_widget("windowsNewCampain", this->window);
    this->builder->get_widget("buttonLevel", this->buttonLevels);
    this->builder->get_widget("buttonBac", this->buttonBack);
    this->builder->get_widget("buttonSav", this->buttonSave);
    this->builder->get_widget("entryName", this->entryName);
    this->builder->get_widget("comboImage", this->comboImage);
    this->builder->get_widget("comboDif", this->comboDif);
    this->builder->get_widget("spinTotalPlayers", this->spinTotalPlayers);
    this->builder->get_widget("spinTotalLevels", this->spinTotalLevels);
    this->builder->get_widget("message", this->message);
    this->builder->get_widget("messageError", this->messageError);
    this->builder->get_widget("buttonOk", this->buttonOk);
    this->builder->get_widget("buttonOk2", this->buttonOk2);
    this->builder->get_widget("buttonCancel", this->buttonCancel);
    this->builder->get_widget("image", this->image);
}

EditarCampania::~EditarCampania() {
    delete this->window;
}

void EditarCampania::connectWidgets() {
    this->window->signal_hide().connect(sigc::mem_fun(this, &EditarCampania::close));
    this->buttonBack->signal_clicked().connect(sigc::mem_fun(this, &EditarCampania::back));
    this->buttonLevels->signal_clicked().connect(sigc::mem_fun(this, &EditarCampania::levelsList));
    this->buttonSave->signal_clicked().connect(sigc::mem_fun(this, &EditarCampania::save));
    this->buttonOk->signal_clicked().connect(sigc::mem_fun(this, &EditarCampania::saveExit));
    this->buttonOk2->signal_clicked().connect(sigc::mem_fun(this, &EditarCampania::hideMessageError));
    this->buttonCancel->signal_clicked().connect(sigc::mem_fun(this, &EditarCampania::cancel));
    this->spinTotalLevels->signal_value_changed().connect(sigc::mem_fun(this, &EditarCampania::incrementLevels));
    this->spinTotalPlayers->signal_value_changed().connect(sigc::mem_fun(this, &EditarCampania::incrementPlayers));
    this->comboDif->signal_changed().connect(sigc::mem_fun(this, &EditarCampania::onComboDifChanged));
    this->comboImage->signal_changed().connect(sigc::mem_fun(this, &EditarCampania::onComboImageChanged));
}

void EditarCampania::getCampaignInfo() {
       this->capaignInfo = this->parserXML.cargarDatos("campaigns/" + this->campaignName);
    string ruta = "campaigns/" + this->campaignName;
    //this->capaignInfo = this->parserXML.cargarDatosIncialesCampania(ruta);
    this->levelsInfo = this->parserXML.cargarNiveles(ruta);
}

void EditarCampania::loadCampaignInfo() {

    this->getCampaignInfo();
    string campaignName = this->capaignInfo.at(0).c_str();
    string pathImage = this->capaignInfo.at(1).c_str();
    string difficult = this->capaignInfo.at(2).c_str();
    int totalPlayers = std::stoi(this->capaignInfo.at(3).c_str());
    int totalLevels =this->levelsInfo.size();//Recuperar cantidad de niveles
    this->campaign.setName(campaignName);
    this->campaign.setPathImage(pathImage);
    this->campaign.setDifficult(difficult);
    this->campaign.setNumberPlayers(totalPlayers);
    this->campaign.setNumberLevels(totalLevels);
    this->entryName->set_text(campaignName);
    this->image->set(pathImage);
    this->comboDif->set_title(difficult);
    this->spinTotalPlayers->set_value(totalPlayers);
    this->spinTotalLevels->set_value(totalLevels);
    this->buttonLevels->set_sensitive(true);
}

void EditarCampania::run() {
    this->window->show();
    this->loadCampaignInfo();
}

void EditarCampania::close() {
    this->window->close();
}

void EditarCampania::back() {
    this->close();
}

void EditarCampania::levelsList() {
    this->window->set_visible(false);
    this->listLevels.setWindowsBack(this->window);
    if (this->levels.empty()) {
        for (unsigned int i = 0; i < this->campaign.getNumberLevels(); i++) {
            Nivel nivel(i, this->campaign.getDifficult(), this->campaign.getNumberPlayers());           
            nivel.setTileMap(this->levelsInfo.at(i).at(3));
            nivel.setName(this->levelsInfo.at(i).at(1));
            this->levels.push_back(nivel);
        }
        this->listLevels.setLevels(&this->levels);
    }
    this->listLevels.editable();
    this->listLevels.run();
}

void EditarCampania::save() {
    string inputText(this->entryName->get_chars(0, -1));
    if (inputText.empty()) {
        //CARTEL
        this->messageError->set_secondary_text("Debe completar el nombre de la campaña", false);
        this->messageError->show();
        return;
    }
    this->campaign.setName(inputText);
    string msjError;
    if (!this->campaign.validate(msjError)) {
        std::cout << "Lanzar mensaje explicando que falta algo" << std::endl;
        this->messageError->set_secondary_text(msjError.c_str(), false);
        this->messageError->show();
        return;
    }
    this->message->show();
}

void EditarCampania::hideMessageError() {
    this->messageError->hide();
}

void EditarCampania::cancel() {
    this->campaign.clear();
    this->message->hide();
}

void EditarCampania::saveExit() {
    vector< vector<string> > levelsInfo;
    for (unsigned int i = 0; i < this->levels.size(); i++) {
        levelsInfo.push_back(this->levels.at(i).getInfo());
    }
    this->campaign.setLevelsInfo(levelsInfo);
    this->campaign.removeSave();
    this->message->hide();
    this->window->hide();

}

void EditarCampania::incrementPlayers() {
    //this->campaign.incrementPlayers();
    this->campaign.setNumberPlayers(spinTotalPlayers->get_value_as_int());
}

void EditarCampania::incrementLevels() {
    this->buttonLevels->set_sensitive(true);
    this->campaign.setNumberLevels(spinTotalLevels->get_value_as_int());
    //this->campaign.incrementLevels();get_value_as_int
}

void EditarCampania::onComboDifChanged() {
    Gtk::TreeModel::iterator iter = comboDif->get_active();
    if (iter) {
        Gtk::TreeModel::Row row = *iter;
        if (row) {
            //Get the data for the selected row, using our knowledge of the tree
            //model:
            Glib::ustring name = row[columnsDiff.colDiffName];
            this->campaign.setDifficult(name);
        }
    } else
        std::cout << "invalid iter" << std::endl;

}

void EditarCampania::onComboImageChanged() {
    Gtk::TreeModel::iterator iter = comboImage->get_active();
    if (iter) {
        Gtk::TreeModel::Row row = *iter;
        if (row) {
            //Get the data for the selected row, using our knowledge of the tree
            //model:campañas
            Glib::ustring name = row[columnsImages.colImageName];
            this->campaign.setPathImage(name);
            this->image->set(name);
            this->image->show();
        }
    } else
        std::cout << "invalid iter" << std::endl;

}

void EditarCampania::createModel() {
    this->createModelDiff();
    this->createModelImages();
}

void EditarCampania::setCampaignName(const string name) {
    this->campaignName = name;
}

void EditarCampania::createModelDiff() {
    //Create the Tree model:
    refTreeModelDiff = Gtk::ListStore::create(columnsDiff);
    comboDif->set_model(refTreeModelDiff);

    //Fill the ComboBox's Tree Model:
    Gtk::TreeModel::Row row = *(refTreeModelDiff->append());
    row[columnsDiff.colDiffName] = "Facil";
    comboDif->set_active(row);
    row = *(refTreeModelDiff->append());
    row[columnsDiff.colDiffName] = "Media";
    row = *(refTreeModelDiff->append());
    row[columnsDiff.colDiffName] = "Dificil";

    comboDif->pack_start(columnsDiff.colDiffName);
}

void EditarCampania::createModelImages() {
    //Create the Tree model:
    refTreeModelImages = Gtk::ListStore::create(columnsImages);
    comboImage->set_model(refTreeModelImages);
    //Fill the ComboBox's Tree Model:
    Gtk::TreeModel::Row row = *(refTreeModelImages->append());
    this->loadImageDirectory(row);
    comboImage->pack_start(columnsImages.colImageName);
}

void EditarCampania::loadImageDirectory(Gtk::TreeModel::Row row) {
    // variables
    string ruta = "img/";
    DIR *dir = NULL;
    struct dirent *drnt = NULL;
    const char* puntos = ".";
    const char* puntos2 = "..";
    dir = opendir(ruta.c_str());
    if (dir) {
        while ((drnt = readdir(dir))) {
            if ((strcmp(drnt->d_name, puntos) == 0) ||
                    ((strcmp(drnt->d_name, puntos2) == 0))) continue;
            stringstream ss;
            ss << drnt->d_name;
            string aux(ss.str());
            row[columnsImages.colImageName] = aux;
            comboImage->set_active(row);
            row = *(refTreeModelImages->append());
        }
        closedir(dir);
    }
}